#pragma once


struct Particle
{
    D3DXVECTOR3 m_vCurPos;
    D3DXVECTOR3 m_vCurVel;
    float       m_fInitTime;

    Particle   *m_pNext;
};

struct PointVertex
{
    D3DXVECTOR3 posit;
    D3DCOLOR    color;

	enum FVF
	{
		FVF_Flags = D3DFVF_XYZ | D3DFVF_DIFFUSE
	};
};

inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }

class ParticleEmitter : public IDrawable
{

public:

    ParticleEmitter(void);
   ~ParticleEmitter(void);

    void SetMaxParticles( DWORD dwMaxParticles ) { m_MaxParticles = dwMaxParticles; }
	DWORD GetMaxParticles( void ) { return m_MaxParticles; }

    void SetNumToRelease( DWORD dwNumToRelease ) { m_NumToRelease = dwNumToRelease; }
	DWORD GetNumToRelease( void ) { return m_NumToRelease; }

    void SetReleaseInterval( float fReleaseInterval ) { m_ReleaseInterval = fReleaseInterval; }
    float GetReleaseInterval( void ) { return m_ReleaseInterval; }

    void SetLifeCycle( float fLifeCycle ) { m_LifeCycle = fLifeCycle; }
	float GetLifeCycle( void ) { return m_LifeCycle; }

    void SetSize( float fSize ) { m_Size = fSize; }
	float GetSize( void ) { return m_Size; }
	float GetMaxPointSize( void ) { return m_MaxPointSize; }

    void SetColor( D3DXCOLOR clrColor ) { m_Color = clrColor; }
	D3DXCOLOR GetColor( void ) { return m_Color; }

    void SetPosition( D3DXVECTOR3 vPosition ) { m_Position = vPosition; }
	D3DXVECTOR3 GetPosition( void ) { return m_Position; }

    void SetVelocity( D3DXVECTOR3 vVelocity ) { m_Velocity = vVelocity; }
	D3DXVECTOR3 GetVelocity( void ) { return m_Velocity; }

    void SetGravity( D3DXVECTOR3 vGravity ) { m_Gravity = vGravity; }
	D3DXVECTOR3 GetGravity( void ) { return m_Gravity; }

    void SetWind( D3DXVECTOR3 vWind ) { m_Wind = vWind; }
	D3DXVECTOR3 GetWind( void ) { return m_Wind; }

    void SetAirResistence( bool bAirResistence ) { m_AirResistence = bAirResistence; }
	bool GetAirResistence( void ) { return m_AirResistence; }

    void SetVelocityVar( float fVelocityVar ) { m_VelocityVar = fVelocityVar; }
	float GetVelocityVar( void ) { return m_VelocityVar; }

    HRESULT Init();
    HRESULT Update( float fElapsedTime );
    void render();

    void SetTexture( const std::string& file );
    LPDIRECT3DTEXTURE9 &GetTextureObject();

    HRESULT RestoreDeviceObjects();
    HRESULT InvalidateDeviceObjects(void);
    
	void RestartParticleSystem(void);

	void SetMinRandomSpread(float min);
	void SetMaxRandomSpread(float max);

	float GetMinRandomSpread();
	float GetMaxRandomSpread();

	static void toLua();

private:

    DWORD       m_VBOffset;
    DWORD       m_Flush;
    DWORD       m_Discard;
    Particle   *m_pActiveList;
    Particle   *m_pFreeList;
	DWORD       m_ActiveCount;
	float       m_CurrentTime;
	float       m_LastUpdate;

    float       m_MaxPointSize;
    bool        m_DeviceSupportsPSIZE;

    LPDIRECT3DVERTEXBUFFER9 m_pVB;
    LPDIRECT3DTEXTURE9      m_ptexParticle;
    
    DWORD       m_MaxParticles;
    DWORD       m_NumToRelease;
    float       m_ReleaseInterval;
    float       m_LifeCycle;
    float       m_Size;
    D3DXCOLOR   m_Color;
    D3DXVECTOR3 m_Position;
    D3DXVECTOR3 m_Velocity;
    D3DXVECTOR3 m_Gravity;
    D3DXVECTOR3 m_Wind;
    bool        m_AirResistence;
    float       m_VelocityVar;
    char       *m_TexFile;

	float m_RandomSpreadMin;
	float m_RandomSpreadMax;
};